package pf

import (
	"chess_platform/internal/alisdk"
	. "chess_platform/internal/common"
	"chess_platform/internal/login"
	"chess_platform/internal/token"
	"chess_platform/models/client"
	"chess_platform/models/partner"
	"chess_platform/modules"
	"fmt"
	"github.com/astaxie/beego/orm"
	"os"
	"time"
)

//[pf]用户
type UserController struct {
	GrantController
}

func (b *UserController) URLMapping() {
	b.Mapping("Player2Agent", b.Player2Agent)
	b.Mapping("MakeAgentFormal", b.MakeAgentFormal)
	b.Mapping("NewIdentity", b.NewIdentity)
	b.Mapping("AgentNum", b.AgentNum)
	b.Mapping("ChangeWeChat", b.ChangeWeChat)
	b.Mapping("SyncWeChat", b.SyncWeChat)
	b.Mapping("Card", b.Card)
	b.Mapping("ChangePassword", b.ChangePassword)
	b.Mapping("BindNewPhone", b.BindNewPhone)
	b.Mapping("UnbindPhone", b.UnbindPhone)
	b.Mapping("Info", b.Info)
	b.Mapping("List", b.List)
	b.Mapping("UpdateBonusRate", b.UpdateBonusRate)
	b.Mapping("UpdateAgentRemark", b.UpdateAgentRemark)
	b.Mapping("UpdatePlayerRemark", b.UpdatePlayerRemark)
	b.Mapping("ManualReview", b.ManualReview)
	b.Mapping("ListManualReview", b.ListManualReview)
	b.Mapping("StatManualReview", b.StatManualReview)
	b.Mapping("Logout", b.Logout)
	b.Mapping("ListNotice", b.ListNotice)
	b.Mapping("NoticeInfo", b.NoticeInfo)
	b.Mapping("NewFeedback", b.NewFeedback)
	b.Mapping("ListFeedbackRecord", b.ListFeedbackRecord)
	b.Mapping("ListHorse", b.ListHorse)
	b.Mapping("RefreshToken", b.RefreshToken)
	b.Mapping("FindPlayer", b.FindPlayer)
}

// @Title 指定玩家成为代理(成为自己下级的代理)
// @Description 指定玩家成为代理(成为自己下级的代理)
// @Param   uid            body   int     true       "玩家的uid"
// @Success 0 {string} 状态码
// @router /player-to-agent [post]
func (b *UserController) Player2Agent() {
	type Params struct {
		Uid int64 `json:"uid" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	err := partner.Player2Agent(p.Uid, b.Uid)
	if err == partner.ErrNoBonusRate || err == partner.ErrNoAgentNum || err == partner.ErrAlreadyAgent {
		b.ResponseFail(err.Error())
		return
	}
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
}

// @Title 修改代理的状态为正式代理(直接跳过第一次充值,免费开通)
// @Description 修改代理的状态为正式代理(直接跳过第一次充值,免费开通)
// @Param   uid            body   int     true       "要审核的用户id"
// @Success 0 {string} 状态码
// @router /make-agent-formal [post]
func (b *UserController) MakeAgentFormal() {
	type Params struct {
		Uid int64 `json:"uid" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	err := modules.InitPartnerAgent(p.Uid, 0)
	if err == MsgAgentAlreadyFormal {
		b.ResponseFail(MsgAgentAlreadyFormal.Error())
		return
	}
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
}

// @Title 新增实名认证
// @Description 新增实名认证
// @Param   identity  	     body    string  true      "身份证号码"
// @Param   real_name        body    string  true      "真实姓名"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /new-identity [post]
func (b *UserController) NewIdentity() {
	type Params struct {
		Identity string `json:"identity"`
		RealName string `json:"real_name"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Length(p.Identity, 18, "identity").Message("身份证号码长度为18位")
	b.Valid.Identity(p.Identity, "identity").Message("请收入正确的身份证,X为大写字母")
	b.Valid.MatchChinese(p.RealName, "real_name").Message("请输入中文")
	b.Valid.MinSize(p.RealName, 2, "real_name").Message("名字长度2-16")
	b.Valid.MaxSize(p.RealName, 16, "real_name").Message("名字长度2-16")
	if !b.VerifyParamsError() {
		return
	}

	data := map[string]interface{}{
		"identity":  p.Identity,
		"real_name": p.RealName,
	}
	//身份认证，纯粹做一下样子
	partner.UpdateUser(data, b.Uid)
	b.ResponseSuccess()

}

// @Title 获取一级代理的名额数
// @Description 获取一级代理的名额数
// @Success 0 {string} rest 为剩下名额
// @Success 1 {string} use  为已使用名额
// @Failure 399
// @router /agent-num [post]
func (b *UserController) AgentNum() {
	field := []string{"agent_num"}
	u, err := partner.SpecifyUserInfoById(b.Uid, field)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	if u == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrAuthCodeNotFound
		b.Response()
		return
	}
	count, err := partner.CountLevel2AgentNum(b.Uid)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	data := map[string]interface{}{
		"rest": u.AgentNum,
		"use":  count,
	}
	b.Res.Data = data
	b.ResponseSuccess()
}

// @Title 更换微信
// @Description 更换微信
// @Param   code       body    string  true      "微信用户code"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /change-weChat [post]
func (b *UserController) ChangeWeChat() {
	field := []string{"login_type"}
	dbUser, err := partner.SpecifyUserInfoById(b.Uid, field)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	if dbUser == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrUserNotFound
		b.Response()
		return
	}
	if dbUser.LoginType != 2 {
		b.ResponseFail("手机登录才可以更换微信")
		return
	}

	type Params struct {
		Code string `json:"code" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	t, err := login.GetWeChatOpenIdAccessToken(p.Code)
	if err != nil {
		LogPF.Error(b.SystemError(err.Error()))
		return
	}
	if t.AccessToken == "" || t.OpenId == "" {
		LogPF.Error(b.SystemError(fmt.Sprintf("无效的open_id:%v\naccess_token:%v\n", t.OpenId, t.AccessToken)))
		return
	}

	//判断微信是否已经绑定了
	uu, err := partner.IsUserExistByOpenID(t.OpenId)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	//已经存在绑定了其它帐号，不能绑定此帐号
	if uu.Uid != 0 { //already exist,can't bind
		b.Res.Code = ErrWeChatAlreadyBind
		b.Res.Msg = MsgErrWeChatAlreadyBind
		b.Response()
		return
	}

	weChat, err := login.GetWeChatUserInfo(t.AccessToken, t.OpenId)
	if err != nil {
		LogPF.Error(b.SystemError(err.Error()))
		return
	}
	if weChat == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrUserNotFound
		b.Response()
		return
	}

	user := map[string]interface{}{
		"open_id":      weChat.OpenID,
		"nickname":     weChat.NickName,
		"sex":          weChat.Sex,
		"province":     weChat.Province,
		"city":         weChat.City,
		"head_img_url": weChat.HeadImgURL,
	}
	_, err = partner.UpdateUser(user, b.Uid)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
}

// @Title 同步微信头像昵称
// @Description 同步微信头像昵称
// @Param   code       body    string  true      "微信用户code"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /sync-weChat [post]
func (b *UserController) SyncWeChat() {
	type Params struct {
		Code string `json:"code" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	t, err := login.GetWeChatOpenIdAccessToken(p.Code)
	if err != nil {
		LogPF.Error(b.SystemError(err.Error()))

		return
	}
	if t.AccessToken == "" || t.OpenId == "" {
		LogPF.Error(b.SystemError(fmt.Sprintf("无效的open_id:%v\naccess_token:%v\n", t.OpenId, t.AccessToken)))
		return
	}

	u, err := partner.IsUserExistByOpenID(t.OpenId)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))

		return
	}
	if u.Uid == 0 { //doesn't exist
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrSyncWeChat
		b.Response()
		return
	}
	//用open_id去找出来的uid是否为b.Uid相等,不相等说明不是本帐号绑定的微信
	if u.Uid != b.Uid { //exist,but didn't match b.Uid
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrSyncWeChat
		b.Response()
		return
	}

	weChat, err := login.GetWeChatUserInfo(t.AccessToken, t.OpenId)
	if err != nil {
		LogPF.Error(b.SystemError(err.Error()))
		return
	}
	if weChat == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrUserNotFound
		b.Response()
		return
	}

	user := map[string]interface{}{
		"open_id":      weChat.OpenID,
		"nickname":     weChat.NickName,
		"sex":          weChat.Sex,
		"province":     weChat.Province,
		"city":         weChat.City,
		"head_img_url": weChat.HeadImgURL,
	}
	_, err = partner.UpdateUser(user, b.Uid)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))

		return
	}
	b.ResponseSuccess()
}

// @Title 代理的名片(个人,下载APP的登录界面)(每次登录时才拉取,缓存在前端本地)
// @Description 代理的名片(个人,下载APP的登录界面)(每次登录时才拉取,缓存在前端本地)
// @Param   type  body    int  true      "2-代理名片,3-下载APP的登录界面"
// @Success 0 {string} QR-code图片文件路径
// @Failure 400
// @Failure 404
// @router /card [post]
func (b *UserController) Card() {
	type Params struct {
		Type int64 `json:"type" valid:"Range(1,3)"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	typeName := ""
	if p.Type == 2 {
		field := []string{"name_url", "head_img_url", "bonus_rate"}
		user, err := partner.SpecifyUserInfoById(b.Uid, field)
		if err != nil {
			LogPF.Error(b.DatabaseError(err.Error()))
			return
		}
		ossPath := ""
		if user != nil && user.NameUrl != "" {
			ossPath = user.NameUrl
		} else {
			ossPath, err = partner.MakePfQRCode(b.Uid, user.HeadImgUrl, typeName)
			if err != nil {
				LogPF.Error(b.DatabaseError(err.Error()))
				return
			}
			qrFile := fmt.Sprintf("pf_name-%v.png", b.Uid)
			os.Remove(qrFile)
			weChatFile := fmt.Sprintf("wechat-%v-%v.jpg", typeName, b.Uid)
			os.Remove(weChatFile)
			wordFile := fmt.Sprintf("word-%v-%v.jpg", typeName, b.Uid)
			os.Remove(wordFile)
			file := fmt.Sprintf("new-name-%v-%v.png", typeName, b.Uid)
			os.Remove(file)
		}
		b.Res.Data = alisdk.GetOssPathUrl(OssDomain) + "/" + ossPath
		b.ResponseSuccess()
	} else {
		typeName = "login"
		field := []string{"login_url", "head_img_url"}
		user, err := partner.SpecifyUserInfoById(b.Uid, field)
		if err != nil {
			LogPF.Error(b.DatabaseError(err.Error()))
			return
		}
		ossPath := ""
		if user != nil && user.LoginUrl != "" {
			ossPath = user.LoginUrl
		} else {
			ossPath, err = partner.MakeLoginQRCode2(b.Uid, user.HeadImgUrl, typeName)
			if err != nil {
				LogPF.Error(b.DatabaseError(err.Error()))
				return
			}
			loginFile := fmt.Sprintf("pf_login-%d.png", b.Uid)
			os.Remove(loginFile)
			weChatFile := fmt.Sprintf("wechat-%v-%v.jpg", typeName, b.Uid)
			os.Remove(weChatFile)
			wordFile := fmt.Sprintf("word-%v-%v.jpg", typeName, b.Uid)
			os.Remove(wordFile)
			file := fmt.Sprintf("new-name-%v-%v.png", typeName, b.Uid)
			os.Remove(file)
		}
		b.Res.Data = map[string]interface{}{
			"login_url":   fmt.Sprintf("%v?agent_uid=%v", QRCode.LoginUrl, b.Uid),
			"qr_code_url": alisdk.GetOssPathUrl(OssDomain) + "/" + ossPath,
		}
		b.ResponseSuccess()
	}

}

// @Title 修改密码
// @Description 修改密码
// @Param   old_password  body    string  true      "旧密码"
// @Param   new_password  body    string  true      "新密码"
// @Success 0 {string} 状态码
// @Failure 399
// @router /change-password [post]
func (b *UserController) ChangePassword() {
	type Params struct {
		OldPassword string `json:"old_password"`
		NewPassword string `json:"new_password"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}

	b.Valid.Required(p.OldPassword, "old_password").Message("密码不能为空")
	b.Valid.MinSize(p.NewPassword, 6, "password").Message("密码长度为6-15个字符")
	b.Valid.MaxSize(p.NewPassword, 15, "password").Message("密码长度为6-15个字符")
	if !b.VerifyParamsError() {
		return
	}
	field := []string{"password"}
	u, err := partner.SpecifyUserInfoById(b.Uid, field)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}

	if u == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrUserNotFound
		b.Response()
		return
	}

	if Md5sum(p.OldPassword) != u.Password {
		b.Res.Code = ErrUserPassword
		b.Res.Msg = MsgErrUserPassword
		b.Response()
		return
	}
	user := map[string]interface{}{
		"password": Md5sum(p.NewPassword),
	}

	_, err = partner.UpdateUser(user, b.Uid)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}

	b.ResponseSuccess()
}

// @Title 手机号绑定
// @Description 手机号绑定
// @Param   phone body    string  true      "手机号"
// @Param   captcha body    string  true      "验证码"
// @Success 0
// @Failure 400
// @Failure 404
// @router /bind-new-phone [post]
func (b *UserController) BindNewPhone() {
	type Params struct {
		Phone   string `json:"phone"`
		Captcha string `json:"captcha"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Required(p.Phone, "phone").Message("手机号不能为空")
	b.Valid.Phone(p.Phone, "phone").Message("错误的手机号")
	b.Valid.Required(p.Captcha, "captcha").Message("验证码不能为空")
	b.Valid.Numeric(p.Captcha, "captcha").Message("验证码为6位数字")
	b.Valid.Length(p.Captcha, 6, "captcha").Message("验证码为6位数字")
	if !b.VerifyParamsError() {
		return
	}
	err, ok := alisdk.VerifySMSCaptcha(p.Phone, p.Captcha, KeyPfPhone, MemCache)
	if !ok {
		b.Res.Code = ErrCaptchaVerify
		b.Res.Msg = err.Error()
		b.Response()
		LogPF.Notice(err.Error())
		return
	}
	uid, err := partner.IsUserExistByPhone(p.Phone)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}

	if uid == b.Uid {
		b.ResponseSuccess("已经绑定,无需重复绑定")
		return
	}
	if uid != 0 {
		b.Res.Code = ErrUserAlreadyExist
		b.Res.Msg = MsgErrPhoneAlreadyExist
		b.Response()
		return
	}

	user := map[string]interface{}{
		"phone": p.Phone,
	}
	_, err = partner.UpdateUser(user, b.Uid)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
}

// @Title 解绑手机号
// @Description 解绑手机号
// @Param   phone     body    string  true      "旧手机号"
// @Param   captcha   body    string  true      "验证码"
// @Success 0 {string} 状态码
// @Failure 399
// @router /unbind-phone [post]
func (b *UserController) UnbindPhone() {
	type Params struct {
		Phone   string `json:"phone"`
		Captcha string `json:"captcha"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}

	b.Valid.Phone(p.Phone, "phone").Message("请输入正确的原手机号")
	b.Valid.Required(p.Captcha, "captcha").Message("验证码不能为空")
	b.Valid.Numeric(p.Captcha, "captcha").Message("验证码为6位数字")
	b.Valid.Length(p.Captcha, 6, "captcha").Message("验证码为6位数字")
	if !b.VerifyParamsError() {
		return
	}

	err, ok := alisdk.VerifySMSCaptcha(p.Phone, p.Captcha, KeyPfPhone, MemCache)
	if !ok {
		b.Res.Code = ErrCaptchaVerify
		b.Res.Msg = err.Error()
		b.Response()
		return
	}

	uid, err := partner.IsUserExistByPhone(p.Phone)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))

		return
	}
	if uid != b.Uid {
		b.ResponseFail("请输入正确的手机号")
		return
	}

	//解绑手机号，所以把手机号置为空传过去就行了
	user := map[string]interface{}{
		"phone": "",
	}
	_, err = partner.UpdateUser(user, b.Uid)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()

}

// @Title 获取自己用户信息
// @Description 获取自己用户信息
// @Success 0 {object} partner.User
// @router /info [post]
func (b *UserController) Info() {
	field := []string{"uid", "nickname", "sex", "head_img_url", "phone", "level",
		"login_type", "identity", "real_name", "bonus_rate", "bonus_rate1", "bonus_rate2"}
	dbUser, err := partner.SpecifyUserInfoById(b.Uid, field)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	if dbUser == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrUserNotFound
		b.Response()
		return
	}
	dbUser.Phone = HidePhoneNumber(dbUser.Phone)
	b.Res.Data = map[string]interface{}{
		"uid":          dbUser.Uid,
		"nickname":     dbUser.Nickname,
		"sex":          dbUser.Sex,
		"head_img_url": dbUser.HeadImgUrl,
		"phone":        dbUser.Phone,
		"level":        dbUser.Level,
		"login_type":   dbUser.LoginType,
		"identity":     dbUser.Identity,
		"real_name":    dbUser.RealName,
		"bonus_rate":   dbUser.BonusRate,
		"bonus_rate1":  dbUser.BonusRate1,
		"bonus_rate2":  dbUser.BonusRate2,
	}
	b.ResponseSuccess()
}

// @Title 获取自己用户信息
// @Description 获取自己用户信息
// @Success 0 {object} partner.User
// @router /bonus-rate [post]
func (b *UserController) BonusRate() {
	field := []string{"level", "root_id", "bonus_rate1", "bonus_rate2"}
	self, err := partner.SpecifyUserInfoById(b.Uid, field)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	if self == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrUserNotFound
		b.Response()
		return
	}
	var bonusRate1 int64
	var bonusRate2 int64
	if self.Level == Level1 {
		bonusRate1 = self.BonusRate1
		bonusRate2 = self.BonusRate2
	} else {
		field = []string{"bonus_rate1", "bonus_rate2"}
		dbUser, err := partner.SpecifyUserInfoById(self.RootId, field)
		if err != nil {
			LogPF.Error(b.DatabaseError(err.Error()))
			return
		}
		if dbUser == nil {
			b.Res.Code = ErrNotFound
			b.Res.Msg = MsgErrUserNotFound
			b.Response()
			return
		}
		bonusRate1 = dbUser.BonusRate1
		bonusRate2 = dbUser.BonusRate2
	}

	b.Res.Data = map[string]interface{}{
		"bonus_rate1": bonusRate1,
		"bonus_rate2": bonusRate2,
	}
	b.ResponseSuccess()
}

// @Title 列出不同等级的合伙人代理(正式代理)
// @Description 列出不同等级合伙人代理(正式代理)
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Param   uid          body   int     false       "代理uid"
// @Success 0 {object} [] 代理列表
// @router /list [post]
func (b *UserController) List() {
	type Params struct {
		Uid int64 `json:"uid"`
		ListParams
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	if p.Uid == 0 {
		p.Uid = b.Uid
	}
	users, count, err := partner.ListLevelUser(p.ListParams, p.Uid)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}

	if len(users) == 0 { //没有更多的二级代理
		b.Res.Count = count
		b.Res.Code = ErrNoData
		b.Res.Msg = MsgErrNoData
		b.Response()
		return
	}

	b.Res.Data = users
	b.Res.Count = count
	b.ResponseSuccess()

}

// @Title 更新直属一级和直属二级提成比例(只有总代才能权限)
// @Description 更新直属一级和直属二级提成比例(只有总代才能权限)
// @Param   type           body    int     false      "1-直属一级,2-直属二级代理提成比例,存储时乘以100"
// @Param   bonus_rate     body    int     false      "直属一级或二级代理提成比例,存储时乘以100"
// @Success 0 {string} 状态码
// @Failure 399
// @router /update-bonus-rate [post]
func (b *UserController) UpdateBonusRate() {
	if b.Level != Level1 {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = MsgErrUserForbidden
		b.Response()
		return
	}
	type Params struct {
		Type      int64 `json:"type" valid:"Range(1,2)"`
		BonusRate int64 `json:"bonus_rate"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	/*
		直属一级与直属二级提成之和不能超过总代的提成
	*/
	field := []string{"bonus_rate", "bonus_rate1", "bonus_rate2"}
	u, err := partner.SpecifyUserInfoById(b.Uid, field)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	if u == nil {
		b.ResponseFail("代理不存在")
		return
	}
	data := make(map[string]interface{}, 1)
	if p.Type == 1 {
		if (p.BonusRate + u.BonusRate2) > u.BonusRate {
			b.ResponseFail(fmt.Sprintf("直属一级与直属二级提成比例之和不能高于%v%%", u.BonusRate/100))
			return
		}
		data["bonus_rate1"] = p.BonusRate
	} else {
		if (p.BonusRate + u.BonusRate1) > u.BonusRate {
			b.ResponseFail(fmt.Sprintf("直属一级与直属二级提成比例之和不能高于%v%%", u.BonusRate/100))
			return
		}
		data["bonus_rate2"] = p.BonusRate
	}
	_, err = partner.UpdateUser(data, b.Uid)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
}

// @Title 更新代理备注
// @Description 更新代理备注
// @Param   uid       body    int     true      "代理id"
// @Param   remark    body    string  true      "备注"
// @Success 0 {string} 状态码
// @Failure 399
// @router /update-agent-remark [post]
func (b *UserController) UpdateAgentRemark() {
	type Params struct {
		Uid    int64  `json:"uid"`
		Remark string `json:"remark"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}

	b.Valid.Required(p.Uid, "uid").Message("代理id不能为空")
	b.Valid.MaxSize(p.Remark, 32, "remark").Message("最多能输入32个字符")
	if !b.VerifyParamsError() {
		return
	}
	u := map[string]interface{}{
		"remark": p.Remark,
	}
	_, err := partner.UpdateUser(u, p.Uid)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))

		return
	}
	b.ResponseSuccess()
}

// @Title 更新玩家备注
// @Description 更新玩家备注
// @Param   player_id        body    int     true      "玩家id"
// @Param   remark           body    string  true      "备注"
// @Success 0 {string} 状态码
// @Failure 399
// @router /update-player-remark [post]
func (b *UserController) UpdatePlayerRemark() {
	type Params struct {
		PlayerId int64  `json:"player_id"`
		Remark   string `json:"remark"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}

	b.Valid.Required(p.PlayerId, "player_id").Message("玩家id不能为空")
	b.Valid.MaxSize(p.Remark, 32, "remark").Message("最多能输入32个字符")
	if !b.VerifyParamsError() {
		return
	}
	u := map[string]interface{}{
		"remark":      p.Remark,
		"create_time": time.Now(),
	}
	_, err := partner.UpdateOrInsertAgentPlayer(u, p.PlayerId, b.Uid)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
}

// @Title 人工审核二级代理
// @Description 人工审核二级代理
// @Param   status         body   int     true       "4-通过，3-不通过"
// @Param   uid            body   int     true       "要审核的用户id"
// @Success 0 {string} 状态码
// @router /manual-review [post]
func (b *UserController) ManualReview() {
	type Params struct {
		Status int64
		Uid    int64
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Range(p.Status, 3, 4, "status").Message("输入不合法")
	b.Valid.Required(p.Uid, "uid").Message("用户id不能为空")
	if !b.VerifyParamsError() {
		return
	}
	//审核之前先判断下二级代理绑定了手机了没有
	field := []string{"status"}
	u, err := partner.SpecifyUserInfoById(p.Uid, field)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	if u.Status < BindPhoneSuccess {
		b.ResponseFail("代理还未绑定手机,请等待")
		return
	}

	o := orm.NewOrm()
	o.Using(DBChessPartner)
	o.Begin()
	defer o.Rollback()

	user := map[string]interface{}{
		"status": p.Status,
	}
	//更新被审核的代理状态
	_, err = partner.UpdateUser(user, p.Uid, o)
	if err != nil {
		o.Rollback()
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}

	//如果审核失败，就还原一个开通代理的名额
	if p.Status == VerifyNotPass {
		//更新自己的代理数加1
		_, err := partner.UpdateUserAgentNum(1, b.Uid, o)
		if err != nil {
			o.Rollback()
			LogPF.Error(b.DatabaseError(err.Error()))
			return
		}
	}
	o.Commit()
	b.ResponseSuccess()

}

// @Title 审核二级代理列表
// @Description 审核二级代理列表
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Success 0 {object} []partner.User
// @router /list-manual-review [post]
func (b *UserController) ListManualReview() {
	var p ListParams
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	users, err := partner.ListManualReviewUser(p, b.Uid)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}

	b.Res.Data = users
	b.ResponseSuccess()
}

// @Title 统计未审核二级代理数
// @Description 统计未审核二级代理数
// @Success 0 {string} 未审核的数量
// @router /stat-manual-review [post]
func (b *UserController) StatManualReview() {
	count, err := partner.StatManualReviewUser(b.Uid)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 代理登出
// @Description 代理登出
// @Success 0 {string} 状态码
// @router /logout [post]
func (b *UserController) Logout() {
	key := fmt.Sprintf("%v%v", KeyPfTokenCache, b.Uid)
	err := RedisCache.Delete(key)
	if err != nil {
		LogPF.Error(b.SystemError(err.Error()))
		return
	}
	b.ResponseSuccess()
}

// @Title H5公告列表(每次登录时拉取)
// @Description H5公告列表(每次登录时拉取)
// @Success 0 {object} []common.H5Notice 公告列表
// @router /list-notice [post]
func (b *UserController) ListNotice() {
	data, err := partner.ListNotice()
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))

		return
	}
	b.Res.Data = data
	b.ResponseSuccess()
}

// @Title H5公告详情
// @Description H5公告详情
// @Param   id   body   int   true        "公告id"
// @Success 0 {object} []common.H5Notice 公告列表
// @router /notice-info [post]
func (b *UserController) NoticeInfo() {
	type Params struct {
		Id int64 `json:"id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	data, err := partner.NoticeInfoById(p.Id)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = data
	b.ResponseSuccess()
}

// @Title 新建h5反馈
// @Description 新建h5反馈
// @Param   uid          body   int        false        "游戏玩家的id"
// @Param   game_name    body   string     false       "游戏名字"
// @Param   type         body   int        true        "标题"
// @Param   content      body   string     true        "内容"
// @Param   url          body   string     true        "多张图片的地址以"["url1","url2","url3"]"形式"
// @Success 0 {string}  状态码
// @router /new-feedback [post]
func (b *UserController) NewFeedback() {
	type Params struct {
		Uid      int64    `json:"uid"`
		GameName string   `json:"game_name"`
		Type     int64    `json:"type"`
		Content  string   `json:"content"`
		Url      []string `json:"url"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if len(p.Url) > 3 {
		b.ResponseFail("最多只能上传三张图片")
		return
	}

	b.Valid.Required(p.Type, "type").Message("请选择反馈类型")
	b.Valid.Required(p.Content, "content").Message("内容不能为空")
	if !b.ValidParams(&p) {
		return
	}
	data := map[string]interface{}{
		"uid":         b.Uid,
		"type":        p.Type,
		"content":     p.Content,
		"status":      0,
		"create_time": time.Now().Unix(),
	}
	o := NewDBOrm(DBChessPartner)
	o.Begin()
	defer o.Rollback()
	fid, err := partner.NewFeedback(data, o)
	if err != nil {
		o.Rollback()
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	dataUrl := map[string]interface{}{
		"fid": fid,
	}
	for _, v := range p.Url {
		dataUrl["url"] = v
		_, err := partner.NewFeedbackUrl(dataUrl, o)
		if err != nil {
			o.Rollback()
			LogPF.Error(b.DatabaseError(err.Error()))
			return
		}
	}
	o.Commit()
	b.ResponseSuccess()
}

// @Title h5用户反馈记录
// @Description h5用户反馈记录
// @Param   uid          body   int        false        "游戏玩家的id"
// @Param   page_size    body   int        true         "每页显示数量"
// @Param   page_index   body   int        true         "第几页"
// @Success 0 {string}  状态码
// @router /list-feedback-record [post]
func (b *UserController) ListFeedbackRecord() {
	type Params struct {
		Uid int64 `json:"uid"`
		ListParams
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	if p.Uid == 0 {
		data, count, err := partner.ListFeedbackRecord(p.ListParams, b.Uid)
		if err != nil {
			LogPF.Error(b.DatabaseError(err.Error()))
			return
		}
		b.Res.Count = count
		b.Res.Data = data
		b.ResponseSuccess()
	}

}

// @Title 跑马灯列表
// @Description 跑马灯列表
// @Success 0 {object} []common.Horse   跑马灯列表
// @router /list-horse  [post]
func (b *UserController) ListHorse() {
	//跑马灯类型,1-游戏客户端, 2-代理助手,3-合伙人系统
	data, err := client.ListHorse(3)
	if err != nil {
		LogPF.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = data
	b.ResponseSuccess()
}

// @Title 刷新token(定时刷新,每隔30分钟)
// @Description 刷新token(定时刷新,每隔30分钟)
// @Success 0 {string} 状态
// @router /refresh-token [post]
func (b *UserController) RefreshToken() {
	tokenStr := token.Create(b.Uid, 0, TokenPF, 1)
	key := fmt.Sprintf("%v%v", KeyPfTokenCache, b.Uid)
	RedisCache.Put(key, tokenStr, time.Duration(Secret.PfTokenCacheExpire)*time.Second)
	b.Res.Token = tokenStr
	b.ResponseSuccess()
}

// @Title 获取玩家信息
// @Description 获取玩家信息,代充前查找玩家id,以便确认
// @Param   uid  body    int     true      "玩家uid"
// @Success 0 {object} client.User
// @router /find-player [post]
func (b *UserController) FindPlayer() {
	type Params struct {
		Uid int64 `json:"uid"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Required(p.Uid, "uid").Message("请输入正确的玩家ID")
	user := client.FindPlayer(p.Uid)
	if user.Uid == 0 {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrUserNotFound
		b.Response()
		return
	}
	b.Res.Data = user
	b.ResponseSuccess()
}
